
#ifndef _JADE_H_
#define _JADE_H_


///////////////////////////////////////////////////////////////////////////////
//Camera 

typedef struct _jade_camera {

    GLfloat m_eyex;
    GLfloat m_eyey;
    GLfloat m_eyez;
    GLfloat m_centerx;
    GLfloat m_centery;
    GLfloat m_centerz;
    GLfloat m_upx;
    GLfloat m_upy;
    GLfloat m_upz;

} jade_camera_t;


///////////////////////////////////////////////////////////////////////////////
//World

typedef struct _jade_world {

    int     m_width;
    int     m_height;
    GLfloat m_bgred;
    GLfloat m_bggreen;
    GLfloat m_bgblue;
    GLfloat m_bgalpha;
    GLfloat m_fovy;
    GLfloat m_znear;
    GLfloat m_zfar;
    jade_camera_t  *m_camera;
//    Fog     *m_fog;
//    Light   *m_light;

} jade_world_t;


///////////////////////////////////////////////////////////////////////////////
//Jade Mesh 

typedef struct _jade_mesh {

        GLfloat     *m_vertices;
        GLfloat     *m_normals;
        GLfloat     *m_uvs;
        GLubyte     *m_colors;
        GLshort     *m_indices;
        GLfloat     *m_position;
        GLfloat     *m_rotate;
        GLfloat     *m_scale;
        GLint       m_textureId;
        GLint       m_triangleNums;
        GLboolean   m_enabled;

        //Add for Texture offset
        GLfloat     *m_texureoffset;

}jade_mesh_t;


///////////////////////////////////////////////////////////////////////////////
///Jade Model 

#define MAX_MESH_COUNT 10

typedef struct _jade_model {

    jade_mesh_t **m_meshes;
    //jade_mesh_t *m_meshes [MAX_MESH_COUNT];
    int m_meshCount;

} jade_model_t;


///////////////////////////////////////////////////////////////////////////////
//Jade Model MD2 

#define MD2_MAX_TRIANGLES		4096
#define MD2_MAX_VERTICES		2048
#define MD2_MAX_TEXCOORDS		2048
#define MD2_MAX_FRAMES			512
#define MD2_MAX_SKINS			32
#define MD2_MAX_FRAMESIZE		(MD2_MAX_VERTICES * 4 + 128)

#define NUMVERTEXNORMALS 162

typedef struct _jade_model_md2_header {
    int magic;
    int version;
    int skinWidth;
    int skinHeight;
    int frameSize;
    int numSkins;
    int numVertices;
    int numTexCoords;
    int numTriangles;
    int numGlCommands;
    int numFrames;
    int offsetSkins;
    int offsetTexCoords;
    int offsetTriangles;
    int offsetFrames;
    int offsetGlCommands;
    int offsetEnd;
}jade_model_md2_header_t;

typedef struct _jade_model_md2_alias_triangleVertex {
    byte vertex[3];
    byte lightNormalIndex;
} jade_model_md2_alias_triangleVertex_t;

typedef struct _jade_model_md2_triangleVertex {
    float vertex[3];
    float normal[3];
    //byte lightNormalIndex;
}jade_model_md2_triangleVertex_t;

typedef struct _jade_model_md2_triangle {
    short vertexIndices[3];
    short textureIndices[3];
}jade_model_md2_triangle_t;

typedef struct _jade_model_md2_textureCoordinate {
    short s, t;
}jade_model_md2_textureCoordinate_t;

typedef struct _jade_model_md2_alias_frame {
    float scale[3];
    float translate[3];
    char name[16];
    jade_model_md2_alias_triangleVertex_t alias_vertices[1];
}jade_model_md2_alias_frame_t;

typedef struct _jade_model_md2_frame {
    char name[16];
    jade_model_md2_triangleVertex_t *vertices;
}jade_model_md2_frame_t;

typedef char jade_model_md2_skin_t[64];

typedef struct _jade_model_md2_action {
    unsigned int index;
    char name[16];
    unsigned int min_idx;
    unsigned int max_idx;
}jade_model_md2_action_t;


typedef struct _jade_model_md2 {

    unsigned int m_frameIdx;
    int          m_actionIdx;
    int          m_actionCount;

    jade_model_md2_header_t            m_header;
    jade_model_md2_skin_t              *m_skins;
    jade_model_md2_textureCoordinate_t *m_texCoords;
    jade_model_md2_triangle_t          *m_triangles;
    jade_model_md2_frame_t             *m_frames;
    jade_model_md2_action_t            *m_actions;

    jade_mesh_t *mesh;

}jade_model_md2_t;

///////////////////////////////////////////////////////////////////////////////
//Jade texture

#define BMP_TORASTER_OFFSET 10
#define BMP_SIZE_OFFSET     18
#define BMP_BPP_OFFSET      28
#define BMP_RLE_OFFSET      30
#define BMP_COLOR_OFFSET    54

typedef struct _jade_texture {
    GLsizei width;
    GLsizei height;
    GLuint textureId;
} jade_texture_t;

typedef struct {
    unsigned char red;
    unsigned char green;
    unsigned char blue;
} Color;



#define fill4B(a)   ( ( 4 - ( (a) % 4 ) ) & 0x03)

///////////////////////////////////////////////////////////////////////////////

typedef struct _jade_font {

    int    m_charWidth;
    int    m_charHeight;
    int    m_colCount;
    int    m_rowCount;
    int    m_fontWidth;
    int    m_fontHeight;
    GLint  m_textureId;


} jade_font_t;


///////////////////////////////////////////////////////////////////////////////
///jade plane

typedef struct _jade_plane {

    jade_mesh_t *mesh;

} jade_plane_t;

///////////////////////////////////////////////////////////////////////////////
///jade skydome

typedef struct _jade_skydome {

    jade_mesh_t *mesh;

} jade_skydome_t;


///////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//API

//camera API

void jade_camera_destroy (jade_camera_t* camera);
void jade_camera_destroy (jade_camera_t* camera);
void jade_camera_set_eye (jade_camera_t *camera, GLfloat eyex, GLfloat eyey, GLfloat eyez);
void jade_camera_set_center (jade_camera_t *camera, GLfloat centerx, GLfloat centery, GLfloat centerz);
void jade_camera_set_up (jade_camera_t *camera, GLfloat upx, GLfloat upy, GLfloat upz);
void jade_camera_glulookat (jade_camera_t *camera);

//world API
jade_world_t* 
jade_world_create (int width, int height, 
        GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);

void jade_world_destroy (jade_world_t *world);
void jade_world_set_camera (jade_world_t *world, jade_camera_t *camera);
void jade_world_prepare_render(jade_world_t* world);

//mesh API

jade_mesh_t* jade_mesh_create ();
void jade_mesh_destroy (jade_mesh_t *mesh);
void jade_mesh_set_triangle_num (jade_mesh_t *mesh, GLint num);
void jade_mesh_set_vertices (jade_mesh_t *mesh, GLfloat *vertices, int size);
void jade_mesh_set_normals (jade_mesh_t *mesh, GLfloat *normals, int size);
void jade_mesh_set_uvs (jade_mesh_t *mesh, GLfloat *uvs, int size);
void jade_mesh_set_colors (jade_mesh_t *mesh, GLubyte *colors, int size);
void jade_mesh_set_indices (jade_mesh_t *mesh, GLshort *indices, int size);
void jade_mesh_set_texture_id (jade_mesh_t *mesh, GLint textureId);
void jade_mesh_set_position (jade_mesh_t *mesh, GLfloat x, GLfloat y, GLfloat z);
void jade_mesh_set_rotate(jade_mesh_t *mesh, GLfloat x, GLfloat y, GLfloat z);
void jade_mesh_set_scale (jade_mesh_t *mesh, GLfloat x, GLfloat y, GLfloat z);
void jade_mesh_set_translate (jade_mesh_t *mesh, GLfloat x, GLfloat y, GLfloat z);
void jade_mesh_set_texture_offset(jade_mesh_t *mesh, GLfloat x, GLfloat y, GLfloat z);
void jade_mesh_render (jade_mesh_t *mesh);

//model API

void jade_model_set_mesh_count (jade_model_t *model, int meshCount);
jade_model_t *jade_model_create (int mesh_count);
void jade_model_destroy (jade_model_t *model);
void jade_model_set_vertices (jade_model_t *model, GLfloat *vertices, int size, int meshIndex);
void jade_model_set_normals (jade_model_t *model, GLfloat *normals, int size, int meshIndex);
void jade_model_set_uvs (jade_model_t *model, GLfloat *uvs, int size, int meshIndex);
void jade_model_set_colors(jade_model_t *model, GLubyte *colors, int size, int meshIndex);
void jade_model_set_indices (jade_model_t *model, GLshort *indices, int size, int meshIndex);
void jade_model_set_triangle_num(jade_model_t *model, GLint triangleNums, int meshIndex);
void jade_model_render (jade_model_t *model);


//md2 model API
int jade_model_md2_get_animation_count(jade_model_md2_t *model);
const char* jade_model_md2_get_animation_name (jade_model_md2_t *model, int animation);
void jade_model_md2_get_animation_frames (jade_model_md2_t *model, 
        int animation, unsigned int *startFrame, unsigned int *endFrame);
void jade_model_md2_set_action_index (jade_model_md2_t *model, int index);
jade_model_md2_t* jade_model_md2_create (char* filename);
void jade_model_md2_destroy (jade_model_md2_t *model);
void jade_model_md2_prepare_frame (jade_model_md2_t *model);
void jade_model_md2_render (jade_model_md2_t *model);
void jade_model_md2_set_rotate (jade_model_md2_t *model, GLfloat x, GLfloat y, GLfloat z);
void jade_model_md2_set_texture_offset(jade_model_md2_t *model, GLfloat x, GLfloat y, GLfloat z);
void jade_model_md2_set_texture_id (jade_model_md2_t *model, GLint textureId);
void jade_model_md2_set_scale (jade_model_md2_t *model, GLfloat x, GLfloat y, GLfloat z);
void jade_model_md2_set_position (jade_model_md2_t *model, GLfloat x, GLfloat y, GLfloat z);

//plane API
jade_plane_t *jade_plane_create (int width, int height, float scale);
void jade_plane_destroy (jade_plane_t *plane);
void jade_plane_set_texture_id (jade_plane_t *plane, GLint textureId);
void jade_plane_set_position (jade_plane_t *plane, GLfloat x, GLfloat y, GLfloat z);
void jade_plane_render (jade_plane_t *plane);

//Sky API
jade_skydome_t *jade_skydome_create (int radius, float dtheta, float dphi);
void jade_skydome_destroy (jade_skydome_t *skydome);
void jade_skydome_set_texture_id (jade_skydome_t *skydome, GLint textureId);
void jade_skydome_set_position (jade_skydome_t *skydome, GLfloat x, GLfloat y, GLfloat z);
void jade_skydome_set_rotate (jade_skydome_t *skydome, GLfloat x, GLfloat y, GLfloat z);
void jade_skydome_render (jade_skydome_t *skydome);



#endif /* _JADE_H_ */
